/*
    组件之间的通信 
    
    1. 父子 组件 
    <A>
        <B></B>
    </A>
    2. 兄弟组件 
    <A></A><B></B>

    props 传递数据
    state 修改数据 

    子组件如何修改父组件
    1. 反向 props  父组件把修改自身变量state的方法 通过 props 传递给子组件 子组件触发 


    
    兄弟组件通信
    1. 中间人模式  子组件A 去修改父组件  父组件再去修改 组件B 
    a. 子改父   反向props  + props
    b. 子改父   反向props  + ref 


    2. 事件机制  bus 事件总线  event (emit on once)
    emit 发送事件
    on 监听事件
    once 监听一次
    remove 移除事件


    架构
    flux  redux mobx  event 


    受控的Input 组件
    受控的组件  input 绑定动态的 value  value 受state 状态控制的  只有state改变 input才能改变
    非受控的组件  value 没有绑定状态 


*/ 
import PropTypes from "prop-types"
import {MyBtn} from "./MyBtn"
import EventEmitter from "events"  // 不需要  node 
const bus = new EventEmitter()   // emit on once  remove  全局通信 
export class Props2 extends Component{ 
  constructor(){
    super()
  }
  state = {
    word:"多去找一个面试资料,自己专研",
    count:1000,
    show:true 
  }
  changeWord=word=>{
    this.setState({
      word 
    })
  }
  changeCount=count=>{
    this.setState({
      count 
    })
  }
  changeShow=show=>{
    this.setState({
      show 
    })
  }
  changeTwoChild=(value)=>{
    this.two.setState({
      text:value 
    })
  }
  render(){
    const {
      word,
      show,
      count 
    } = this.state 
    return (
      <div>
        <h2> React 组件通信 -- 子改父 (兄弟组件通信 )</h2>
        <h4>word -- {word }</h4>
        <h4>count == {count}</h4>
        <div
        style={{width:150,height:150,background:'darkred',borderRedius:10,display:show?'block':'none'}}
        >
          我是被子组件  控制的 
        </div>
        <hr/>
        <ChildOne
          word={word}
          changeWord={this.changeWord}
          changeCount={this.changeCount}
          count={count}
          show={show}
          changeShow={this.changeShow}
          changeTwoChild={this.changeTwoChild}
        ></ChildOne>
        <hr/>
        <ChildTwo
          word={word}
          show={show}
          ref={el=>this.two=el}
        ></ChildTwo>
      </div>
    )
  }
}

class ChildOne extends Component{
  handleChange=(e)=>{
    this.props.changeWord(e.target.value)
  }

  handleEmit=()=>{
    bus.emit("wqedassadsadeqwqewewasd","hello wh2107")
  }
  render(){
    const {
      word ,
      changeCount ,
      count,
      changeShow,
      show ,
      changeTwoChild
    } = this.props
    return (
      <div>
        <h2> 子组件 - 1 - childone </h2>
        <p>
          <input type="text"  value={word}  onChange={this.handleChange}  />
        </p>
        <MyBtn  text="change count "  onClick={()=>changeCount(count+10)}    />
        <MyBtn  text="change Show "  onClick={()=>changeShow(!show)  }    />
        <MyBtn  text="ref 去修改组件 two  text"  onClick={()=>changeTwoChild('wh2107-vue项目上线了吗')  }    />
        <MyBtn  text="event 事件机制直接修改 组件two   text "  onClick={ this.handleEmit  }    />
      </div>
    )
  }
}

ChildOne.propTypes = {
  word:PropTypes.string.isRequired 
}

// slot 插槽 
const arr = ["花好月圆","圆圆满满","满门抄斩","斩草除根","根深蒂固","固若金汤","汤臣一品"]
class ChildTwo extends Component{
  state = {
    text:"2107-daydayup"
  }
  componentDidMount(){
    bus.on("wqedassadsadeqwqewewasd",msg=>{
      this.setState({
        text:msg
      })
    })
  }
  render(){
    const {word,show } = this.props;
    const {text}  = this.state;
    return (
      <div>
        <h2> 子组件 - 2 - ChildTwo </h2>
        <h4>word == {word} </h4>
        <h4>text == {text}</h4>
        {
          show?<h4>有十足的信心找工作 </h4>: <h4> 一定要自己多动手 </h4>
        }
        <MyList txt="LOve message">
             {arr}
        </MyList>
      </div>
    )
  }
}


// react 插槽  this.props.children  
class MyList extends Component{
  render(){
    console.log(this)
    return (
      <div>
        <h2> List - List - lsit </h2>
        {
          this.props.children && this.props.children.map((l,i)=>{
            return (
              <h4 key={i}> {l} -- {i} </h4>
            )
          })
        }
        <Mytext>
          <h1>Area YOu oK?</h1>
           <h3>hello world</h3>
        </Mytext>
      </div>
    )
  }
}

const list = [2101,2103,2105,2107,2110];
class Mytext extends Component{
  render(){
    return (
      <div>
        <h2> Mytext - Mytext- Mytext</h2>
        {
          this.props.children 
        }
        <MyDemo id="2107" game="lol" time="1022">
            {
              list
            }
        </MyDemo>
      </div>
    )
  }
}

// 纯函数接收 props+children 

function MyDemo({id,game,time,children}){
  // console.log(props)
  return (
    <div>
      <h2> 
      MyDemo - MyDemo - MyDemo
      </h2>
      <h4>{children}</h4>
      <p>
        props - {id} - {game} - {time}
      </p>
    </div>
  )
}